/*
 * @(#)ProcessTraceManager.java
 * 2012-9-11 下午02:21:15
 * 
 *
 * Copyright (c) 2018-2028, HangZhou QiYun InfoTech Co.,Ltd. .
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.qyxx.platform.gsmng.common.service;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.zip.ZipInputStream;

import org.activiti.engine.ActivitiException;
import org.activiti.engine.FormService;
import org.activiti.engine.HistoryService;
import org.activiti.engine.IdentityService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.delegate.Expression;
import org.activiti.engine.form.FormProperty;
import org.activiti.engine.form.TaskFormData;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.impl.Condition;
import org.activiti.engine.impl.RepositoryServiceImpl;
import org.activiti.engine.impl.bpmn.behavior.MultiInstanceActivityBehavior;
import org.activiti.engine.impl.bpmn.behavior.UserTaskActivityBehavior;
import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.el.ExpressionManager;
import org.activiti.engine.impl.el.UelExpressionCondition;
import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.interceptor.CommandExecutor;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.PvmActivity;
import org.activiti.engine.impl.pvm.PvmTransition;
import org.activiti.engine.impl.pvm.delegate.ActivityBehavior;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.task.TaskDefinition;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.IdentityLink;
import org.activiti.engine.task.Task;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.qyxx.platform.common.module.web.FormatMessage;
import com.qyxx.platform.common.module.web.Messages;
import com.qyxx.platform.common.orm.Page;
import com.qyxx.platform.common.orm.PropertyFilter;
import com.qyxx.platform.common.utils.encode.JsonBinder;
import com.qyxx.platform.common.utils.web.struts2.Struts2Utils;
import com.qyxx.platform.gsc.cache.TableEntityCache;
import com.qyxx.platform.gsmng.common.dao.GsMngDao;
import com.qyxx.platform.gsmng.common.dao.ProcessDefDao;
import com.qyxx.platform.gsmng.common.dao.ProcessInfoDao;
import com.qyxx.platform.gsmng.common.dao.ProcessModelInfoDao;
import com.qyxx.platform.gsmng.common.dao.TaskInstanceDao;
import com.qyxx.platform.gsmng.common.dao.TaskRunDao;
import com.qyxx.platform.gsmng.common.entity.ProcessDefinitionInstance;
import com.qyxx.platform.gsmng.common.entity.ProcessInfo;
import com.qyxx.platform.gsmng.common.entity.ProcessModelInfo;
import com.qyxx.platform.gsmng.common.entity.TaskInstance;
import com.qyxx.platform.gsmng.common.entity.TaskRun;
import com.qyxx.platform.sysmng.accountmng.dao.RoleDao;
import com.qyxx.platform.sysmng.accountmng.dao.UserDao;
import com.qyxx.platform.sysmng.accountmng.entity.Organization;
import com.qyxx.platform.sysmng.accountmng.entity.Role;
import com.qyxx.platform.sysmng.accountmng.entity.RoleJson;
import com.qyxx.platform.sysmng.accountmng.entity.User;
import com.qyxx.platform.sysmng.accountmng.service.AccountManager;
import com.qyxx.platform.sysmng.desktop.dao.DesktopDao;
import com.qyxx.platform.sysmng.desktop.dao.DesktopToUserDao;
import com.qyxx.platform.sysmng.desktop.entity.Desktop;
import com.qyxx.platform.sysmng.desktop.entity.DesktopToUser;
import com.qyxx.platform.sysmng.desktop.service.DesktopToUserManager;
import com.qyxx.platform.sysmng.utils.Constants;



/**
 *  流程跟踪服务，用于显示流程图流转信息
 *  @author gxj
 *  @version 1.0 2012-9-11 下午02:21:15
 *  @since jdk1.6 
 */
@Service
@Transactional
public class ProcessTraceManager {
	
	private static Logger logger = LoggerFactory.getLogger(ProcessTraceManager.class);
	
	/**
	 * 查询语句
	 */
	private static final String QUERY_PROCESSINFO_HQL = "from ProcessInfo t where t.processInstanceId = ? and t.activitiId = ? order by t.dealTime desc";
	
	private static final String TASKS = "select a.ID_,a.PROC_INST_ID_,a.PROC_DEF_ID_," +
	"a.NAME_,a.ASSIGNEE_,a.CREATE_TIME_ from ACT_RU_TASK a " +
	"where a.ASSIGNEE_ = ? or (a.ASSIGNEE_ is null and exists(select b.ID_ from ACT_RU_IDENTITYLINK b " +
	"where b.TASK_ID_ = a.ID_ and b.USER_ID_ = ? )) order by a.CREATE_TIME_ desc";
	
	private static final String ALLUSER_TASKS = "select (CASE WHEN a.ASSIGNEE_ IS null THEN b.USER_ID_ ELSE a.ASSIGNEE_ END) username from ACT_RU_TASK a left join ACT_RU_IDENTITYLINK b on a.ID_ = b.TASK_ID_";
		
	private static final String DEL_PROCESSINFO = "delete from ProcessInfo  p where p.processInstanceId = ?";
	
	private static final String SEL_PROCESS_MODEL_INFO = "from ProcessModelInfo  p where p.businessKey = ? order by p.id desc";
	
	private static final JsonBinder jsonBinder = JsonBinder.getAlwaysMapper();
	
	public static final String APPROVE_DESP = "_approveDesp_";
	
	@Autowired
	protected RuntimeService runtimeService;

	@Autowired
	protected TaskService taskService;

	@Autowired
	protected RepositoryService repositoryService;

	@Autowired
	protected IdentityService identityService;
	
	@Autowired
	protected HistoryService historyService;
	
	@Autowired
	private ProcessInfoDao processInfoDao;
	
	@Autowired
	private ProcessModelInfoDao processModelInfoDao;
	// 主实体Dao
	private GsMngDao gsMngDao;
	
	private FormService	formService;
	
	private ProcessEngineConfigurationImpl processEngineConfigurationImpl;
	
    private DesktopToUserDao desktopToUserDao;
	 
	private DesktopDao desktopDao;
	
	private TaskInstanceDao taskInstanceDao;
	
	private DesktopToUserManager desktopToUserManager;
	
	private ProcessDefDao processDefDao;
	
	private TaskRunDao taskRunDao;
	
	private RoleDao roleDao;
	
	private GsMngManager gsMngManager;
	
	private User user;
	
	private AccountManager accountManager;
	
	private UserDao userDao;
	
	@Autowired
	public void setGsMngDao(GsMngDao gsMngDao) {
		this.gsMngDao = gsMngDao;
	}
	@Autowired
	public void setGsMngManager(GsMngManager gsMngManager) {
		this.gsMngManager = gsMngManager;
	}
	
	@Autowired
	public void setRoleDao(RoleDao roleDao) {
		this.roleDao = roleDao;
	}

	@Autowired
	public void setTaskRunDao(TaskRunDao taskRunDao) {
		this.taskRunDao = taskRunDao;
	}

	@Autowired
	public void setProcessDefDao(ProcessDefDao processDefDao) {
		this.processDefDao = processDefDao;
	}

	@Autowired
	public void setTaskInstanceDao(TaskInstanceDao taskInstanceDao) {
		this.taskInstanceDao = taskInstanceDao;
	}

	@Autowired
	public void setDesktopToUserManager(
			DesktopToUserManager desktopToUserManager) {
		this.desktopToUserManager = desktopToUserManager;
	}

	@Autowired
	public void setDesktopToUserDao(DesktopToUserDao desktopToUserDao) {
			this.desktopToUserDao = desktopToUserDao;
	}
		
	@Autowired
	public void setDesktopDao(DesktopDao desktopDao) {
			this.desktopDao = desktopDao;
	}

	@Autowired
	public void setFormService(FormService formService) {
		this.formService = formService;
	}

	@Autowired
	public void setIdentityService(IdentityService identityService) {
		this.identityService = identityService;
	}

	@Autowired
	public void setProcessEngineConfigurationImpl(
			ProcessEngineConfigurationImpl processEngineConfigurationImpl) {
		this.processEngineConfigurationImpl = processEngineConfigurationImpl;
	}


	@Autowired
	public void setProcessInfoDao(ProcessInfoDao processInfoDao) {
		this.processInfoDao = processInfoDao;
	}

	@Autowired
	public void setRuntimeService(RuntimeService runtimeService) {
		this.runtimeService = runtimeService;
	}

	@Autowired
	public void setTaskService(TaskService taskService) {
		this.taskService = taskService;
	}

	@Autowired
	public void setHistoryService(HistoryService historyService) {
		this.historyService = historyService;
	}

	@Autowired
	public void setRepositoryService(
			RepositoryService repositoryService) {
		this.repositoryService = repositoryService;
	}
	@Autowired
	public void setProcessModelInfoDao(
			ProcessModelInfoDao processModelInfoDao) {
		this.processModelInfoDao = processModelInfoDao;
	}
	
	/**
	 * @param userDao
	 */
	@Autowired
	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}
	/**
	 * @return user
	 */
	public User getUser() {
		return user;
	}
	
	/**
	 * @param user
	 */
	public void setUser(User user) {
		this.user = user;
	}
	
	/**
	 * @param accountManager
	 */
	@Autowired
	public void setAccountManager(AccountManager accountManager) {
		this.accountManager = accountManager;
	}
	/**
	 * 流程未启动时获取流程定义实体类（主要用于流程未启动前获取下一个环节的角色信息；范围：只在本类中使用）
	 */
	public ProcessDefinitionEntity getCurrentProcessDefinition(final String processDefinitionKey) {
		CommandExecutor commandExecutor = processEngineConfigurationImpl
				.getCommandExecutor();
				ProcessDefinitionEntity processDefinition = commandExecutor
				.execute(new Command<ProcessDefinitionEntity>() {

					public ProcessDefinitionEntity execute(
							CommandContext commandContext) {
					//return	commandContext.getProcessDefinitionManager().findLatestProcessDefinitionByKey(processDefinitionKey);
						return Context
								.getProcessEngineConfiguration()
								.getDeploymentManager()
								.findDeployedLatestProcessDefinitionByKey(processDefinitionKey);

					}
				});
				
	//ProcessDefinitionEntity def = (ProcessDefinitionEntity) ((RepositoryServiceImpl)repositoryService).getDeployedProcessDefinition(processDefinitionKey);
				
				return processDefinition;
	}

	/**
	 * 流程未启动时获取起点事件的下一个环节候选组的角色（范围：只在本类中使用）
	 */

	public String getStartNextTaskGroups(String processDefinitionKey,String businessKey) {	
		ProcessDefinitionEntity processDefinition = getCurrentProcessDefinition(processDefinitionKey);
		String groups = "";
		// DeploymentCache deploymentCache = Context
		// .getProcessEngineConfiguration().getDeploymentCache();
		// processDefinition = deploymentCache
		// .findDeployedLatestProcessDefinitionByKey("contract");
		// processDefinition = (ProcessDefinitionEntity) repositoryService
		// .createProcessDefinitionQuery()
		// .processDefinitionKey("test").latestVersion()
		// .singleResult();
		//final ExecutionEntity execution = processDefinition.createProcessInstance(businessKey);
		List<ActivityImpl> activitiList = processDefinition
				.getActivities();
		for (ActivityImpl activityImpl : activitiList) {

			if ("startEvent".equals(activityImpl.getProperty("type"))) {
				 // 获得起点事件
				groups = this.getStartNextTask(activityImpl,processDefinition,businessKey);
				break;
			}
		}
		return groups;
	}
	/**
	 * 获取启动事件后面下一个userTask任务（公用方法，主要用于迭代查找启动事件的下一个任务；范围：只在getStartNextTaskGroups方法中使用）
	 */
	public String getStartNextTask(ActivityImpl activityImpl,final ProcessDefinitionEntity processDefinition,final String businessKey) {
		String groups = "";
		List<PvmTransition> outTransitions = activityImpl
				.getOutgoingTransitions();// 获取从某个节点出来的所有线路
		for (PvmTransition tr : outTransitions) {
			PvmActivity ac = tr.getDestination(); // 获取线路的终点节点
			if ("userTask".equals(ac.getProperty("type"))) {
				groups = getCandidateGroupRole(ac);
				break;
			}else if ("serviceTask".equals(ac.getProperty("type"))) {
				groups =  this.getStartNextTask((ActivityImpl) ac,processDefinition, businessKey);
			}else if ("exclusiveGateway".equals(ac.getProperty("type"))) {
				CommandExecutor commandExecutor = processEngineConfigurationImpl
						.getCommandExecutor();
				final ExecutionEntity execution = commandExecutor
						.execute(new Command<ExecutionEntity>() {

							public ExecutionEntity execute(
									CommandContext commandContext) {
								return processDefinition
										.createProcessInstance(businessKey);
							}
						});
				String pId = execution.getProcessInstanceId();
				List<PvmTransition> outTransitionsTemp = ac
						.getOutgoingTransitions();
				for (PvmTransition tr1 : outTransitionsTemp) {
					Object s = tr1.getProperty("conditionText");
					ExpressionManager expressionManager = processEngineConfigurationImpl
							.getExpressionManager();
					final Condition expressionCondition = new UelExpressionCondition(
							expressionManager.createExpression(s
									.toString()));
					/*
					 * CommandExecutor commandExecutor =
					 * processEngineConfigurationImpl
					 * .getCommandExecutorTxRequired();
					 */
					Boolean bn = commandExecutor
							.execute(new Command<Boolean>() {

								public Boolean execute(
										CommandContext commandContext) {
									return expressionCondition
											.evaluate(execution);
								}
							});
					if (bn) {
						runtimeService.deleteProcessInstance(pId, "");
						historyService
								.deleteHistoricProcessInstance(pId);
						PvmActivity ac1 = tr1.getDestination();
						if ("userTask"
								.equals(ac1.getProperty("type"))) {
							groups = getCandidateGroupRole(ac1);
							break;
						} else if ("serviceTask".equals(ac1
								.getProperty("type"))) {
							groups =  this.getStartNextTask((ActivityImpl) ac1,
									processDefinition, businessKey);
							break;
						}else if ("endEvent".equals(ac1
							.getProperty("type"))) {
							break;
						}
					}

				}
			} else if("parallelGateway".equals(ac
					.getProperty("type"))) {
				List<PvmTransition>	outGoTransitionsTemp = ac.getOutgoingTransitions();
				List<String> groupList = Lists.newArrayList();
				for (PvmTransition pt : outGoTransitionsTemp) {
					PvmActivity ac1 = pt.getDestination();
					if ("userTask"
							.equals(ac1.getProperty("type"))) {
						String group = getCandidateGroupRole(ac1);
						groupList.add(group);
					} else if ("serviceTask".equals(ac1
							.getProperty("type"))) {
						String group =  this.getStartNextTask((ActivityImpl) ac1,
								processDefinition, businessKey);
						groupList.add(group);
					}
				}
				groups = StringUtils.join(groupList, ",");
			}
		}
		return groups;
	}
	/**
	 * 运行中获取下一节点    （公用方法；主要用于迭代查找当前任务的下一个任务，范围：只在本类中使用）
	 */
	public PvmActivity getNextTask(String procInstanceId,String variableName,String value, String taskId) {
		PvmActivity pa =null;
		/*List<Task> tasks = taskService.createTaskQuery()
				.processInstanceId(procInstanceId).list();
		// historyService.createHistoricProcessInstanceQuery().processInstanceId(procInstanceId).singleResult().getProcessDefinitionId();
		for (Task task : tasks) {*/
		Task task = taskService.createTaskQuery().taskId(taskId)
				.singleResult();
		ProcessDefinitionEntity def = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
				.getDeployedProcessDefinition(task
						.getProcessDefinitionId());
		List<ActivityImpl> activitiList = def.getActivities();
		String excId = task.getExecutionId();

		final ExecutionEntity execution = (ExecutionEntity) runtimeService
				.createExecutionQuery().executionId(excId)
				.singleResult();

		String activitiId = execution.getActivityId();// 当前执行的ID
		for (ActivityImpl activityImpl : activitiList) {
			String id = activityImpl.getId();
			if (activitiId.equals(id)) {
				// System.out.println("当前任务："+
				// activityImpl.getProperty("name"));
				// 输出当前节点的某种属性
				pa = getUserTask(activityImpl, execution,
						variableName, value);
				return pa;
			}
		}
		//}
		return pa;
	}
	/**
	 * 获取  Task的PvmActivity对象（主要用于 获取 下一个任务的PvmActivity对象，范围：只在本类中使用）
	 */
	public PvmActivity getUserTask(PvmActivity pvm,
			final ExecutionEntity execution, String variableName,
			String value) {
		PvmActivity pa = null;
		ActivityImpl activityImpl = (ActivityImpl) pvm;
		List<PvmTransition> outTransitions = activityImpl
				.getOutgoingTransitions();// 获取从当前节点可能流出的所有线路

		List<PvmTransition> outTransitionsTemp = null;
		for (PvmTransition tr : outTransitions) {
			PvmActivity ac = tr.getDestination(); // 获取线路中当前节点的，下一个环节
			if ("exclusiveGateway".equals(ac.getProperty("type"))) {// 假如下一个分支节点
				outTransitionsTemp = ac.getOutgoingTransitions();
				if (outTransitionsTemp.size() == 1) {
					return outTransitionsTemp.get(0).getDestination();
					// return getCandidateGroupRole(outTransitionsTemp
					// .get(0).getDestination());
				} else if (outTransitionsTemp.size() > 1) {
					for (PvmTransition tr1 : outTransitionsTemp) {
						Object s = tr1.getProperty("conditionText");
						runtimeService.setVariable(execution.getId(),
								variableName, value);

						ExpressionManager expressionManager = processEngineConfigurationImpl
								.getExpressionManager();
						final Condition expressionCondition = new UelExpressionCondition(
								expressionManager.createExpression(s
										.toString()));
						CommandExecutor commandExecutor = processEngineConfigurationImpl
								.getCommandExecutor();
						Boolean bn = commandExecutor
								.execute(new Command<Boolean>() {

									public Boolean execute(
											CommandContext commandContext) {

										return expressionCondition
												.evaluate(execution);
									}
								});

						if (bn) {
							PvmActivity ac1 = tr1.getDestination();
							if("userTask".equals(ac1
									.getProperty("type"))) {
								return ac1;
							}else if ("serviceTask".equals(ac1
									.getProperty("type")) || "exclusiveGateway".equals(ac1.getProperty("type"))) {
								pa = getUserTask(ac1, execution,
										variableName, value);
								break;
							}else if ("parallelGateway".equals(ac1
									.getProperty("type"))) {
								List<PvmTransition>	outGoTransitionsTemp = ac1.getOutgoingTransitions();
								for (PvmTransition pt : outGoTransitionsTemp) {
									PvmActivity ac2 = pt.getDestination();
									if("userTask".equals(ac2.getProperty("type"))) {
										return ac2;
									}else{
										return null;
									}
								}
							}else if ("endEvent".equals(ac1
									.getProperty("type"))) {
								return null;
							} else {
								return null;
								}
							}
						}
					}
				}else if ("userTask".equals(ac.getProperty("type"))) {// 假如下一个节点是直接是用户环节
					return ac;
				}else if ("callActivity".equals(ac
						.getProperty("type"))) {
					return null;
				}else if ("serviceTask".equals(ac
						.getProperty("type"))) {
					pa = getUserTask(ac, execution,
							variableName, value);
				}else if ("parallelGateway".equals(ac
						.getProperty("type"))) {
					List<PvmTransition>	outGoTransitionsTemp = ac.getOutgoingTransitions();
					for (PvmTransition pt : outGoTransitionsTemp) {
						PvmActivity ac2 = pt.getDestination();
						if("userTask".equals(ac2.getProperty("type"))) {
							return ac2;
						}else{
							return null;
						}
					}
				}	
		}
		return pa;
	}
	/**
	 * 获取task任务中自定义的角色
	 */
	public String getNextRoles(String processInstanceId,String processDefinitionKey,
			String variableName,String value,String businessKey, String taskId) {

		String roles = "";
		if (StringUtils.isBlank(processInstanceId)) {
			roles = getStartNextTaskGroups(processDefinitionKey,businessKey);//未启动流程时
		} else {
			roles = getCandidateGroupRole(getNextTask(processInstanceId,variableName,value,taskId));//启动流程过程中
		}
		
		return roles;
	}
	
	/**
	 * 根据角色获取用户集合
	 */
	public List<User> getUserList(String roles, User currentUser, Long bid, String proInsId) {
		List<User> list = new ArrayList<User>();
		if (StringUtils.isNotBlank(roles)) {
			String rids[] = roles.split(",");
			for (String ss : rids) {
				if(ss.startsWith("$$")) {//表示sql获取规则
					String assignRuleKey = ss.substring(2);
					Map<String, Object> paramMap = new HashMap<String, Object>();
					if(bid == null) {//业务ID为空时，使用流程实例ID去获取
						bid = (Long)this.getBusinessKeyByProInsId(proInsId).get("id");
					}
					paramMap.put("id", bid);
					User user = findUserBySqlKey(assignRuleKey, paramMap);
					if(Constants.ENABLED.equals(user.getStatus())) {
						list.add(user);
					}
				} else if(ss.startsWith("$")) {//表示获取同组织内的用户
					ss = ss.substring(1);
					String orgCode = currentUser.getOrganization().getOrganizationCode();
					List<String> orgCodeList = Organization.getSplitCodeList(orgCode);
					List<User> uList = roleDao.findUserByRoleNameAndOrgCode(ss, orgCodeList);
					list.addAll(uList);
				} else {
					Role r = roleDao.findUniqueBy("roleName", ss);
					List<User> uList = r.getUserList();
					if(null!=uList && !uList.isEmpty()) {
						for(User u : uList) {
							if(Constants.ENABLED.equals(u.getStatus())) {
								list.add(u);
							}
						}
					}
				}
			}
		}
		return list;
	}
	
	/**
	 * 根据规则key获取环节处理用户
	 * @param ruleKey
	 * @param map
	 * @return
	 */
	public User findUserBySqlKey(String ruleKey, Map<String, Object> map) {
		String idVal = processInfoDao.getStringValueByParam(map, ruleKey, "");
		User user = accountManager.getUser(Long.valueOf(idVal));
		return user;
	}
	
	/**
	 * 根据流程实例ID获取业务ID和实体名
	 * @param processInstanceId
	 * @return
	 */
	public Map<String, Object> getBusinessKeyByProInsId(String processInstanceId) {
		String bKey = this.getBusinessKey(processInstanceId);
		String a[] = bKey.split("\\|");
		String moduleKey = a[0];
		Long moduleId = Long.valueOf(a[1]);
		Map<String, Object> map = Maps.newHashMap();
		map.put("entityName", moduleKey);
		map.put("id", moduleId);
		return map;
	}
	
	/**
	 * 获取用户树
	 */
	public List<RoleJson> getUserTree(String roles,User currentUser, Long bid, String proInsId){
		List<RoleJson> list = new ArrayList<RoleJson>();
		Set<User> set = new HashSet<User>();
		if (StringUtils.isNotBlank(roles)) {
			String currentCode = currentUser.getOrganization().getOrganizationCode();
			String rids[] = roles.split(",");
			for (String ss : rids) {
				List<User> uList = null;
				if(ss.startsWith("$$")) {//表示sql获取规则
					String assignRuleKey = ss.substring(2);
					Map<String, Object> paramMap = new HashMap<String, Object>();
					if(bid == null) {//业务ID为空时，使用流程实例ID去获取
						bid = (Long)this.getBusinessKeyByProInsId(proInsId).get("id");
					}
					paramMap.put("id", bid);
					User user = findUserBySqlKey(assignRuleKey, paramMap);
					if(Constants.ENABLED.equals(user.getStatus()) && set.add(user)) {
						RoleJson ur = new RoleJson(user, 0L);
						ur.setChecked(true);
						list.add(ur);
					}
				} else {
					if(ss.startsWith("$")) {//表示获取同组织内的用户
						ss = ss.substring(1);
						String orgCode = currentUser.getOrganization().getOrganizationCode();
						List<String> orgCodeList = Organization.getSplitCodeList(orgCode);
						uList = roleDao.findUserByRoleNameAndOrgCode(ss, orgCodeList);
					}
					Role r = roleDao.findUniqueBy("roleName", ss);
					RoleJson rj = new RoleJson(r.getId(),
							r.getRoleName(), r.getOrganization().getId());
					rj.setNocheck(true);
					list.add(rj);
					if(uList == null) {
						uList = r.getUserList();
					}
					if(null!= uList) {
						for (User u : uList) {
							if (Constants.ENABLED.equals(u.getStatus()) && set.add(u)) {//启用用户
							//if (!u.getId().equals(currentUser.getId()) //排除当前用户
							//		&& set.add(u)) {
								RoleJson ur = new RoleJson(u, r.getId());
								String code = u.getOrganization()
										.getOrganizationCode();
								/*if (currentCode.indexOf(code) >= 0
										|| code.indexOf(currentCode) >= 0) {
									ur.setChecked(true);
								}*/
								if(currentCode.startsWith(code)) {
									//默认上级和本级选中
									ur.setChecked(true);
								}/*
								if(currentCode.equals(code)) {
									//默认本级选中
									ur.setChecked(true);
								}*/
								list.add(ur);
							}
						}
					}
				}
			}
		}
		return list;
	}
	
	/**
	 * 启动流程
	 * 
	 */
	public void startWorkflow(ProcessInfo entity,
			Map<String, Object> variables, String uIds,User user,String processDefinitionKey) {

		String mark = "";
		entity.setDealName(user.getLoginName());
		entity.setUserId(user.getId());
		gsMngManager.setEntityName(entity.getBusinessName());
		identityService.setAuthenticatedUserId(user.getLoginName());//设置驳回的执行人
		String processDefinitionId = "";
		//多实例时下一个环节的设置候选用户（范围：只在多实例时使用）
		ProcessDefinitionEntity processDefinition = getCurrentProcessDefinition(processDefinitionKey);
		processDefinitionId = processDefinition.getId();
		if (StringUtils.isNotBlank(uIds)) {		
		List<ActivityImpl> activitiList = processDefinition
				.getActivities();
		for (ActivityImpl activityImpl : activitiList) {
			if ("startEvent".equals(activityImpl.getProperty("type"))) {
				List<PvmTransition> outTransitions = activityImpl
						.getOutgoingTransitions();// 获取从某个节点出来的所有线路
				for (PvmTransition tr : outTransitions) {
					PvmActivity ac = tr.getDestination(); // 获取线路的终点节点
					ActivityImpl ai = (ActivityImpl) ac;
					ActivityBehavior activityBehavior = ai.getActivityBehavior();
					if (activityBehavior instanceof MultiInstanceActivityBehavior) {// 流程多实例的选择用户
						 mark = "MultiInstance";
						MultiInstanceActivityBehavior multiInstanceActivityBehavior = (MultiInstanceActivityBehavior) activityBehavior;
						String CollectionVariable = multiInstanceActivityBehavior
								.getCollectionVariable();
							String userids[] = uIds.split(",");
							
							List<String> s = new ArrayList<String>();
							for (String ss : userids) {
								s.add(ss);
							
							variables.put(CollectionVariable, s);
							
						}
					}
				}
			}
		}
	}
		if(StringUtils.isNotBlank(processDefinitionId)){
			List<FormProperty> fp = formService.getStartFormData(processDefinitionId).getFormProperties();
			for(FormProperty fpy : fp){
				String fid = fpy.getId();			
				if(("titleName").equals(fid)){ //任务名后缀字段
					Map<String, Object> module = gsMngManager.getEntity(entity.getBusinessId());
					Object val = module.get(fpy.getName());
					variables.put("FieldData",val);
					break;
				} else if("titleRuleKey".equals(fid)) { //任务名后缀规则key
					variables.put("taskTitleRuleKey",fpy.getName());
					break;
				}
			}
		}
		String businessKey = entity.setBusinessKey(
				entity.getBusinessName(), entity.getBusinessId());
		variables.put("startUser", user.getLoginName());
		variables.put("countVao", 1L);
		variables.put("handleUserId", user.getId());//当前处理人ID
		variables.put("handleUserLoginName", user.getLoginName());//当前处理人登录名
		ProcessInstance processInstance = runtimeService
				.startProcessInstanceByKey(processDefinitionKey, businessKey,
						variables);
		// 通过获取key，得到流程实例
		String processInstanceId = processInstance.getId();	
		entity.setProcessInstanceId(processInstanceId);
		entity.setDealTime(new Date());
		//runtimeService. setVariable(processInstanceId, "countVao", 1L);		
		entity.setCountVal(1L);
		entity.setTaskName("发起申请");
		//将审批备注加入开始环节日志
		String approveDesp = (String)variables.get(APPROVE_DESP);
		if(approveDesp != null) entity.setReason(approveDesp);
		
		HistoricProcessInstance hpi = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
		entity.setActivitiId(hpi.getStartActivityId());

		processInfoDao.save(entity);
		// 保存流程信息
		
		if (StringUtils.isNotBlank(uIds) && !mark.equals("MultiInstance")){
		setTaskCandidateUser(uIds,processInstanceId); 
		// 非多实例设置候选用户.
		}
		gsMngManager.setEntityName(entity.getBusinessName());
		gsMngManager.updateFlowColumn(entity.getBusinessId(),gsMngManager.STATUS_APPROVAL,processInstanceId );
		//更新合同表字段
		
		HistoricProcessInstance historicProcessInstance	= historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).finished().singleResult();
		if(historicProcessInstance!=null){//数据流的情况，判断流程实例是否结束
			String activitiIdEnd =historicProcessInstance.getEndActivityId();
			Date endTime = historicProcessInstance.getEndTime();
			ProcessInfo pi = new ProcessInfo();
			pi.setBusinessName(entity.getBusinessName());
			pi.setBusinessId(entity.getBusinessId());
			pi.setDealName(user.getLoginName());
			pi.setDealTime(endTime);
			pi.setUserId(user.getId());
			pi.setProcessInstanceId(processInstanceId);
			pi.setActivitiId(activitiIdEnd);
			pi.setCountVal(1L);
			pi.setTaskName("结束申请");
			processInfoDao.save(pi);// 保存流程结束信息
			gsMngManager.updateFlowColumn(entity.getBusinessId(),GsMngManager.STATUS_FINISH,null);
		}

	}

	/**
	 * 桌面上的查询待办任务列表
	 * 
	 */
	public DesktopToUser findTasks(Long desktopId ,Long userId,String userName) {
//		List<Task> tasks = new ArrayList<Task>();
//		// 根据当前人的用户名查询，该用户参与的流程
//		List<Task> todoList = taskService.createTaskQuery()
//				.taskAssignee(userName).orderByTaskPriority().desc()
//				.orderByTaskCreateTime().desc().list();
//		// 根据当前人未签收的任务
//		List<Task> unsignedTasks = taskService.createTaskQuery()			
//				.taskCandidateUser(userName).orderByTaskPriority()
//				.desc().orderByTaskCreateTime().desc().list();
//		// 合并
//		tasks.addAll(todoList);
//		tasks.addAll(unsignedTasks);
		DesktopToUser desktopToUser= desktopToUserManager.findDesktopToUser(desktopId, userId).get(0);
		List<Map<String, Object>> list=Lists.newArrayList();
		
		Desktop desktop=desktopDao.get(desktopId);
		String sourceType=desktop.getSourceType();
		String source=desktop.getSource();
		Long displayNum=desktop.getDisplayNum();
		if(sourceType.endsWith("sql")){
			Map<String, Object> param=new HashMap<String, Object>();
			param.put("userName", userName);
			list=desktopToUserDao.findDataList(source, displayNum.intValue(), param);
		}
		
		for(Map<String, Object> taskMap :list ){
		String processInstanceId = (String) taskMap.get("processInstanceId");
		HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
		String startUser = historicProcessInstance.getStartUserId();
		String bKey = historicProcessInstance.getBusinessKey();
		if(StringUtils.isBlank(bKey)){//如果取不到businessKey，说明运行到了子流程
			bKey = (String) runtimeService.getVariable(processInstanceId,"varInBusinessKey");
		}

		Object fieldData = runtimeService.getVariable(processInstanceId,"FieldData");
		if(null!=fieldData){
			taskMap.put("field", fieldData);
		}
		String a[] = bKey.split("\\|");
		String  moduleKey = a[0];
		Long moduleId = Long.valueOf(a[1]);
		
		String b[] = moduleKey.split("\\.");
		String mName = b[0];
		String moduleName = TableEntityCache.getInstance().getModuleName(mName);
		taskMap.put("startUser", startUser);
		taskMap.put("moduleId", moduleId);
		taskMap.put("moduleName", moduleName);
		}
		desktopToUser.setList(list);
		return desktopToUser;
	}
	
	/**
	 * 统计所有用户的所有待办事件数量
	 * 
	 */
	public List<Map<String, Object>> findAllUserTasksNum() {
		return gsMngDao.findBy(ALLUSER_TASKS, null);
	}
	
	/**
	 * 统计待办事件数量
	 * 
	 */
	public Long findTasksNum(Page<Map<String, Object>> page,String userName) {	
		//Map<String, Object> param=new HashMap<String, Object>();
		//param.put("userName", userName);
		//Long count = desktopToUserDao.findDataListCount(TASKS,param);
		Long count = gsMngDao.getTotalCountBySql(TASKS, userName, userName);
		return count;
	}
	
	/**
	 * 查询待办任务列表
	 * 
	 */
	public Page<Map<String, Object>> findAllTasks(Page<Map<String, Object>> page,String userName) {
		List<Map<String, Object>> list=Lists.newArrayList();
		//Map<String, Object> param=new HashMap<String, Object>();
		//param.put("userName", userName);
		//page = desktopToUserDao.findDataPage(page,TASKS,param);
		page = gsMngDao.pagedQuery(TASKS, page, userName, userName);
		list = page.getResult();
		for(Map<String, Object> taskMap :list ){
			taskMap.put("id", taskMap.get("ID_"));
			taskMap.put("processInstanceId", taskMap.get("PROC_INST_ID_"));
			taskMap.put("procDefId",taskMap.get("PROC_DEF_ID_"));
			taskMap.put("name", taskMap.get("NAME_"));
			taskMap.put("assignee", taskMap.get("ASSIGNEE_"));
			taskMap.put("createTime", taskMap.get("CREATE_TIME_"));
			String processInstanceId = (String) taskMap.get("processInstanceId");
			HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
			String startUser = historicProcessInstance.getStartUserId();
			String bKey = historicProcessInstance.getBusinessKey();
			if(StringUtils.isBlank(bKey)){//如果取不到businessKey，说明运行到了子流程
				bKey = (String) runtimeService.getVariable(processInstanceId,"varInBusinessKey");
			}
			Object fieldData = runtimeService.getVariable(processInstanceId,"FieldData");
			if(null!=fieldData){
				taskMap.put("field", fieldData);
			}
			String a[] = bKey.split("\\|");
			String  moduleKey = a[0];
			Long moduleId = Long.valueOf(a[1]);
			
			//查询有无任务标题规则key
			String taskTitleRuleKey = (String)runtimeService.getVariable(processInstanceId,"taskTitleRuleKey");
			if(StringUtils.isNotBlank(taskTitleRuleKey)) {
				final Map<String, Object> paramMap = new HashMap<String, Object>();
				paramMap.put("id",moduleId);
				paramMap.put("handleUserId", runtimeService.getVariable(processInstanceId,"handleUserId"));
				String titleSuffix = processInfoDao.getStringValueByParam(paramMap, taskTitleRuleKey, "");
				taskMap.put("field", titleSuffix);
			}
			
			String b[] = moduleKey.split("\\.");
			String mName = b[0];
			String moduleName = TableEntityCache.getInstance().getModuleName(mName);
			taskMap.put("startUser", startUser);
			taskMap.put("startUserCaption", userDao.getUserNameByLoginName(startUser));//查询用户姓名
			taskMap.put("moduleId", moduleId);
			taskMap.put("moduleName", moduleName);
		}		
		page.setResult(list);
		return page;
	}
	/**
	 * 查询流程定义对象
	 * 
	 * @param processDefinitionId
	 *            流程定义ID
	 * @return
	 */
	protected ProcessDefinition getProcessDefinition(
			String processDefinitionId) {
		ProcessDefinition processDefinition = repositoryService
				.createProcessDefinitionQuery()
				.processDefinitionKey(processDefinitionId)
				.singleResult();
		return processDefinition;
	}

	/**
	 * 签收任务
	 */
	public void signFor(String tid, String userName) {
		taskService.claim(tid, userName);
	}
	
	/**
	 * 获取任务
	 * 如果未签收，先签收任务，最后返回任务
	 * 
	 * @param taskId
	 * @param user
	 * @return
	 */
	public Task signFor(String taskId, User user) {
		Task task = getTaskById(taskId);
		String name = task.getAssignee();
		if (StringUtils.isBlank(name)) {
			//记录接收任务日志
			ProcessInfo pi = new ProcessInfo();
			String processInstanceId = task.getProcessInstanceId();
			HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
			String bKey = historicProcessInstance.getBusinessKey();
			if(StringUtils.isBlank(bKey)){//如果取不到businessKey，说明运行到了子流程
				bKey = (String) runtimeService.getVariable(processInstanceId,"varInBusinessKey");
			}
			String a[] = bKey.split("\\|");
			String moduleKey = a[0];
			Long moduleId = Long.valueOf(a[1]);
			pi.setBusinessName(moduleKey);
			pi.setBusinessId(moduleId);
			pi.setTaskId(taskId);
			pi.setDealName(user.getLoginName());
			pi.setDealTime(new Date());
			pi.setUserId(user.getId());
			pi.setProcessInstanceId(task.getProcessInstanceId());
			pi.setActivitiId(task.getTaskDefinitionKey());
			pi.setExecutionId(task.getExecutionId());
			pi.setCountVal(1L);
			pi.setTaskName("接收任务");
			processInfoDao.save(pi);//保存流程结束信息
			this.signFor(taskId, user.getLoginName());
		}
		runtimeService.setVariable(task.getProcessInstanceId(), "handleUserId", user.getId());//当前处理人ID
		runtimeService.setVariable(task.getProcessInstanceId(), "handleUserLoginName", user.getLoginName());//当前处理人登录名
		return task;
	}


	/**
	 * 获取流程中的BusinessKey
	 */
	public String getBusinessKey(String processInstanceId) {
	/*	ProcessInstance processInstance = runtimeService
				.createProcessInstanceQuery()
				.processInstanceId(processInstanceId).singleResult();
		String businessKey = processInstance.getBusinessKey();*/
		HistoricProcessInstance hpi = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
		String businessKey =  hpi.getBusinessKey();
		
		if(StringUtils.isBlank(businessKey)){//如果取不到businessKey，说明有子流程
			String varInBusinessKey = (String) runtimeService.getVariable(processInstanceId,"varInBusinessKey");
			return varInBusinessKey;
		}
		return businessKey;
	}

	/**
	 * 获取userTask环节的CandidateGroup表达式（范围：只在本类使用）
	 */

	public String getCandidateGroupRole(PvmActivity ac) {
		String  expressionText ="";
		if(ac!=null){
		ActivityImpl ai = (ActivityImpl) ac;

		ActivityBehavior activityBehavior = ai.getActivityBehavior();
		TaskDefinition taskDefinition = null;
		if (activityBehavior instanceof UserTaskActivityBehavior) {
			UserTaskActivityBehavior userTaskActivityBehavior = (UserTaskActivityBehavior) activityBehavior;
			taskDefinition = userTaskActivityBehavior
					.getTaskDefinition();
		} else if (activityBehavior instanceof MultiInstanceActivityBehavior) {
			MultiInstanceActivityBehavior multiInstanceActivityBehavior = (MultiInstanceActivityBehavior) activityBehavior;
		
			taskDefinition = multiInstanceActivityBehavior
					.getTaskDefinition();
		}
		Set<Expression> candidateGroupIdExpressions = taskDefinition
				.getCandidateGroupIdExpressions();
		List<String> list = new ArrayList<String>();
		 	for (Expression  expression:candidateGroupIdExpressions) {
		 		String exp = expression.getExpressionText();
		 		list.add(exp);
		 	}
		 	expressionText = StringUtils.join(list, ",");
		}
		return expressionText;
	}

	/**
	 * 完成环节任务
	 */
	public void completeTask(ProcessInfo processInfo,
			Map<String, Object> map, User user, String userIds) {
		processInfo.setDealName(user.getLoginName());
		processInfo.setDealTime(new Date());
		processInfo.setUserId(user.getId());
		String processInstanceId = processInfo.getProcessInstanceId();
		Object times= runtimeService.getVariable(processInstanceId , "countVao");
		String key="";
		String value="";
		String isApprove="";
		//记录流程流向信息
		for (Object obj : map.keySet()) {
			 key = String.valueOf(obj);
			 value = String.valueOf(map.get(obj));
			if (key.equals("approve")&& !value.equals("")) {
				isApprove = value;
				processInfo.setIsApprove(value);
				Long countVal = (Long)times;
				processInfo.setCountVal(countVal);
			}
			else if(key.equals("resend")&& !value.equals("")){
				Long countVal = (Long)times;
				countVal++;
				processInfo.setCountVal(countVal);
				runtimeService. setVariable(processInstanceId, "countVao", countVal);
			}
		}
	
		ProcessInstance processInstance = runtimeService
				.createProcessInstanceQuery()
				.processInstanceId(processInstanceId).singleResult();
	
		String businessKey = processInstance.getBusinessKey();
		if(StringUtils.isBlank(businessKey)){//如果取不到businessKey，说明运行到了子流程
			 businessKey = (String) runtimeService.getVariable(processInstanceId,"varInBusinessKey");
		}
		String[] bKey = processInfo.splitBusinessKey(businessKey);
		processInfo.setBusinessName(bKey[0]);
		processInfo.setBusinessId(Long.valueOf(bKey[1]));

		String taskId = processInfo.getTaskId();
		Task task = getTaskById(taskId);

		processInfo.setActivitiId(task.getTaskDefinitionKey());	
		processInfoDao.save(processInfo);// 保存流程信息实体类
		//下一个环节为多实例时的设置候选用户（在多实例时必须先设置审批用户，再完成当前任务；)
		//原因是：多实例环节需要根据审批人数来动态创建下一环节的任务数量
		setNextTaskCandidateUser(userIds,processInstanceId,map,key,value,taskId);
			
		taskService.complete(taskId, map);// 完成流程任务	

		setTaskCandidateUser(userIds,processInstanceId); // 当前环节为非多实例设置候选用户.（在非多实例时可以先完成当前任务，再设置审批用户）

		HistoricProcessInstance historicProcessInstance	= historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).finished().singleResult();
		if(historicProcessInstance!=null){//判断流程实例是否结束
			String activitiIdEnd =historicProcessInstance.getEndActivityId();
			Date endTime = historicProcessInstance.getEndTime();
			ProcessInfo pi = new ProcessInfo();
			pi.setBusinessName(bKey[0]);
			pi.setBusinessId(Long.valueOf(bKey[1]));
			pi.setDealName(user.getLoginName());
			pi.setDealTime(endTime);
			pi.setUserId(user.getId());
			pi.setProcessInstanceId(processInstanceId);
			pi.setActivitiId(activitiIdEnd);
			pi.setCountVal((Long)times);
			pi.setTaskName("结束申请");
			processInfoDao.save(pi);// 保存流程结束信息
			gsMngManager.setEntityName(processInfo.getBusinessName());
			if("1".equals(isApprove)){
				gsMngManager.updateFlowColumn(Long.valueOf(bKey[1]),GsMngManager.STATUS_PASS,null);
			}else{
				gsMngManager.updateFlowColumn(Long.valueOf(bKey[1]),GsMngManager.STATUS_NO_PASS,null);
			}
		}
	}
	
	/**
	 * 批量同意任务
	 * 
	 * @param ids
	 * @param entityName
	 * @param userIds
	 * @param user
	 */
	public void batchStartProcess(Long[] ids, String entityName, String userIds, User user) {
		String moduleKey = StringUtils.split(entityName, ".")[0];
		Map<String, Object> variables = new HashMap<String, Object>();
		for(Long id : ids) { //批量启动操作
			ProcessInfo pi = new ProcessInfo();
			pi.setBusinessId(id);
			pi.setBusinessName(entityName);
			startWorkflow(pi, variables, userIds, user, moduleKey);
		}
	}
	
	/**
	 * 批量同意任务
	 * 
	 * @param taskIds
	 * @param userIds
	 * @param user
	 */
	public void batchAgree(String[] taskIds, String userIds, User user, String approveFlag, String approveKey) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put(StringUtils.defaultIfEmpty(approveKey, "approve"), approveFlag);//同意参数
		for(String taskId : taskIds) { //批量同意操作
			Task task = signFor(taskId, user);
			ProcessInfo pi = new ProcessInfo();
			pi.setTaskId(task.getId());
			pi.setTaskName(task.getName());
			pi.setExecutionId(task.getExecutionId());
			pi.setProcessInstanceId(task.getProcessInstanceId());
			completeTask(pi,map,user,userIds);
		}
	}
	
	/**
	 * 批量同意
	 * 
	 * @param taskIds
	 * @param userIds
	 * @param user
	 */
	public void batchAgree(String[] taskIds, String userIds, User user, String approveKey) {
		batchAgree(taskIds, userIds, user, "1", approveKey);
	}
	
	/**
	 * 批量不同意
	 * 
	 * @param taskIds
	 * @param userIds
	 * @param user
	 */
	public void batchDisAgree(String[] taskIds, String userIds, User user, String approveKey) {
		batchAgree(taskIds, userIds, user, "0", approveKey);
	}

	/**
	 * 获取流程的Task
	 * 
	 */
	@Transactional(readOnly = true)
	public Task getTaskById(String tid) {
		Task task = null;
		task = taskService.createTaskQuery().taskId(tid).singleResult();
		return task;

	}
	
	/**
	 * 批量启动流程（只针对每个环节仅有一个用户参数审批操作）
	 * 
	 * @param ids
	 * @param entityName
	 * @param moduleName
	 * @param currentUser
	 * @return
	 */
	public String batchStartProcessForSingleUser(Long[] ids, String entityName, String moduleName, User currentUser) {
		StringBuffer sb = new StringBuffer("");
		for(Long id : ids) {
			ProcessInfo pi = new ProcessInfo();
			String businessKey = pi.setBusinessKey(entityName, id);
			String roles = this.getNextRoles(
					null, moduleName, null,
					null, businessKey, null);
			if (StringUtils.isNotBlank(roles)) {
				List<User> userList = this.getUserList(roles, currentUser, id, null);
				if (userList.size() >= 1) {
					String uId = userList.get(0).getLoginName();
					this.batchStartProcess(new Long[]{id}, entityName, uId, currentUser);
				} else {
					throw new RuntimeException("编号为" + id + "的数据下一环节["+roles+"]角色中没有设置用户");
				}		
			} else {
				this.batchStartProcess(new Long[]{id}, entityName, "", currentUser);
			}
		}
		return sb.toString();
	}
	
	/**
	 * 批量同意/不同意流程（只针对每个环节仅有一个用户参数审批操作）
	 * 
	 * @param ids
	 * @param entityName
	 * @param currentUser
	 * @param approveFlag
	 * @return
	 */
	public String batchAgreeForSingleUser(String[] ids, String entityName, User currentUser, String approveFlag, String approveKey) {
		StringBuffer sb = new StringBuffer("");
		for(String taskId : ids) {
			Task tk = this.getTaskById(taskId);
			String pdk = tk.getProcessDefinitionId();
			String moduleName = StringUtils.split(pdk, ":")[0];
			String roles = this.getNextRoles(
					tk.getProcessInstanceId(), moduleName, StringUtils.defaultIfEmpty(approveKey, "approve"),
					approveFlag,"",taskId);
			if (StringUtils.isNotBlank(roles)) {
				List<User> userList = this.getUserList(roles, currentUser, null, tk.getProcessInstanceId());
				if (userList.size() >= 1) {
					String uId = userList.get(0).getLoginName();
					this.batchAgree(new String[]{taskId}, uId, currentUser, approveFlag, approveKey);
				}else{
					throw new RuntimeException("编号为" + taskId + "的任务下一环节["+roles+"]角色中没有设置用户");
				}		
			} else {
				this.batchAgree(new String[]{taskId}, "", currentUser, approveFlag, approveKey);
			}
		}
		return sb.toString();
	}

	/**
	 * 查询流程信息.
	 */
	@Transactional(readOnly = true)
	public Page<ProcessInfo> searchProcess(
			final Page<ProcessInfo> page,
			final List<PropertyFilter> filters) {
		Page<ProcessInfo> p = processInfoDao.findPage(page, filters);
		List<ProcessInfo> list = p.getResult();
		if(list != null) {
			for(ProcessInfo pi : list) {
				pi.setUserName(userDao.getUserNameById(pi.getUserId()));
			}
		}
		return p;
	}

	/**
	 * 利用了Activiti的From信息用来辨别.
	 */
	@Transactional(readOnly = true)
	public Map<String,Object> getFormData(String taskId){
		Map<String,Object> formData = Maps.newHashMap();
		TaskFormData taskFormData =  formService.getTaskFormData(taskId);
		List<FormProperty> fp = taskFormData.getFormProperties();
		for(FormProperty fpy : fp){
			String fid = fpy.getId();
			if(StringUtils.isNotBlank(fid)){
				/*if(fid.equals("rpt")){
					formData.put("rpt",fpy.getName());
				}else if(fid.equals("roles")){
					formData.put("roles",fpy.getName());
				}else if(fid.equals("modify")){
					formData.put("modify",fpy.getName());
				}else if(fid.equals("button")){
					formData.put("button",fpy.getName());					
				}else if(fid.equals("approve_title")){
					formData.put("approve_title",fpy.getName());					
				}else if(fid.equals("reject_title")){				
					formData.put("reject_title",fpy.getName());	
				}else{				
					formData.put("again",fpy.getName());
				}*/
				formData.put(fid, fpy.getName());
			}
		}
		return formData;
	}

	
	/**
	 * 获取流程运行时变量
	 * 
	 * @param proInsId
	 * @param key
	 * @return
	 */
	public Object getVariable(String proInsId, String key) {
		return runtimeService.getVariable(proInsId, key);
	}
	
	/**
	 * 非多实例设置候选用户.（范围：只在本类使用）
	 */
	public void setTaskCandidateUser(String userIds,String processInstanceId){
		// runtimeService.setVariable(processInstanceId, "CandidateUser", "");
		// 非多实例
		List<Task> tasksList = taskService.createTaskQuery()
				.processInstanceId(processInstanceId).list();
		for (Task tasks : tasksList) {
			ProcessDefinitionEntity def = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
					.getDeployedProcessDefinition(tasks
							.getProcessDefinitionId());
			List<ActivityImpl> activitiList = def.getActivities();
			String excId = tasks.getExecutionId();

			ExecutionEntity execution = (ExecutionEntity) runtimeService
					.createExecutionQuery().executionId(excId)
					.singleResult();
			String activitiId = execution.getActivityId();// 当前执行的ID
			for (ActivityImpl activityImpl : activitiList) {
				if (activitiId.equals(activityImpl.getId())) {
					// activityImpl//当前的执行活动
					ActivityBehavior activityBehavior = activityImpl
							.getActivityBehavior();
					if (activityBehavior instanceof UserTaskActivityBehavior) {// 非多实例
						String cUser = (String) runtimeService
								.getVariable(processInstanceId,
										"CandidateUser");
						if (StringUtils.isNotBlank(cUser)) {
							runtimeService.setVariable(
									processInstanceId,
									"CandidateUser", "");
						}

						if (StringUtils.isNotBlank(userIds)) {
							String groupId = getCandidateGroupRole(activityImpl);// 候选组角色
							String tid = tasks.getId();
							taskService.deleteCandidateGroup(tid,
									groupId);
							String userId[] = userIds.split(",");
							
							boolean isParallel = false;//上一节点是否并行分支
							List<PvmTransition> inTrans = activityImpl.getIncomingTransitions();
							if(!inTrans.isEmpty()) {
								PvmActivity pa = inTrans.get(0).getSource();
								if("parallelGateway".equals(pa.getProperty("type"))) {
									isParallel = true;
								}
							}
							if(isParallel) { //并行分支
								//需要查找用户是不是该分支角色下的用户
								for (String uId : userId) {
									User tmpUser = accountManager.findUserByLoginName(uId);
									if(tmpUser != null && tmpUser.isHaveRole(groupId)) {
										taskService.addCandidateUser(tid, uId);
									}
								}
							} else { //其他情况
								for (String uId : userId) {
									taskService.addCandidateUser(tid, uId);
								}
							}
						}
					}
				}
			}
		}
	}
	/**
	 * 多实例设置候选用户.（范围：只在本类使用）
	 * <存在问题>
	 * 
	 * 重点：（1：如何获取下一个环节；2：如何获取当前环节）
	 */
	  
	public void setNextTaskCandidateUser(String userIds,String processInstanceId,Map<String , Object> map,String variableName,String value,String taskId){
		//下一个环节的设置
		if (StringUtils.isNotBlank(userIds)) {
		PvmActivity ac = getNextTask(processInstanceId,variableName,value,taskId);//获取当前环节的下一个userTask
		if(ac!=null){
			ActivityImpl ai = (ActivityImpl)ac;
			ActivityBehavior activityBehavior = ai.getActivityBehavior();
			if (activityBehavior instanceof MultiInstanceActivityBehavior) {// 流程多实例的选择用户
				
				MultiInstanceActivityBehavior multiInstanceActivityBehavior = (MultiInstanceActivityBehavior) activityBehavior;
				String CollectionVariable = multiInstanceActivityBehavior
						.getCollectionVariable();
				// 自定义设置委托组
			
				String cUser = (String)runtimeService.getVariable(processInstanceId, "CandidateUser");
				if(StringUtils.isNotBlank(cUser)){
					userIds = userIds+","+cUser;
				}
				
				
				//判断当前活动是不是单实例,
				List<Task> tasksList = taskService.createTaskQuery()
				.processInstanceId(processInstanceId).list();
				for (Task tasks : tasksList ) {
			ProcessDefinitionEntity def = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
					.getDeployedProcessDefinition(tasks
							.getProcessDefinitionId());
			List<ActivityImpl> activitiList = def.getActivities();
			String excId = tasks.getExecutionId();

			ExecutionEntity execution = (ExecutionEntity) runtimeService
					.createExecutionQuery().executionId(excId)
					.singleResult();
			String activitiId = execution.getActivityId();// 当前执行的ID  userTask1
			for (ActivityImpl activityImpl : activitiList) {
				if (activitiId.equals(activityImpl.getId())) {
				//	activityImpl//当前的执行活动
					ActivityBehavior activityBehaviorCurrent = activityImpl.getActivityBehavior();
					if (activityBehaviorCurrent instanceof MultiInstanceActivityBehavior) {//判断当前的执行活动是否为多实例
						runtimeService.setVariable(processInstanceId, "CandidateUser", userIds);
					}
				}
			}
		}	
					String userids[] = userIds.split(",");	
					Set<String> set = new HashSet<String>();
					List<String> s = new ArrayList<String>();
					for (String ss : userids) {
						if(set.add(ss)){//去重复
						s.add(ss);
							}
					}
					map.put(CollectionVariable, s);
					}
				}
			}
		}	
	/**
	 * 设置任务描述
	 */
	public void setTaskDescription(String taskId,String description){
		Task ti = taskService.createTaskQuery().taskId(taskId).singleResult();
		ti.setDescription(description);
		taskService.saveTask(ti);

	}
	/**
	 * 设置任务转派用户
	 */
	public void delegateUser(String taskId,String userId, User user){
		taskService.delegateTask(taskId, userId);
		//记录任务转派日志
		Task task = this.getTaskById(taskId);
		if(null!=task) {
			ProcessInfo pi = new ProcessInfo();
			pi.setTaskId(taskId);
			pi.setExecutionId(task.getExecutionId());
			String proInsId = task.getProcessInstanceId();
			ProcessInstance processInstance = runtimeService
					.createProcessInstanceQuery()
					.processInstanceId(proInsId).singleResult();
			String businessKey = processInstance.getBusinessKey();
			if(StringUtils.isBlank(businessKey)){//如果取不到businessKey，说明运行到了子流程
				 businessKey = (String) runtimeService.getVariable(proInsId,"varInBusinessKey");
			}
			String[] bKey = pi.splitBusinessKey(businessKey);
			pi.setBusinessName(bKey[0]);
			pi.setBusinessId(Long.valueOf(bKey[1]));
			pi.setProcessInstanceId(proInsId);
			pi.setDealName(user.getLoginName());
			pi.setDealTime(new Date());
			pi.setUserId(user.getId());
			pi.setActivitiId(task.getTaskDefinitionKey());
			pi.setCountVal(1L);
			pi.setTaskName(task.getName());
			pi.setReason("[" + user.getLoginName() + "]将任务转派给[" + userId + "]");
			processInfoDao.save(pi);//保存转派日志信息
		}
	}
	/**
	 * 设置下一个环节的下推数据选人
	 */
	public void setFormUser(String taskId,String userId){	
		taskService. setVariable(taskId, "formUser", userId);
	}
	/**
	 * 挂起流程实例
	 */
	public void suspendProcessInst(String processInstanceId){	
		runtimeService.suspendProcessInstanceById(processInstanceId);
	}
	
	/**
 	* 激活流程实例
 	*/
	public void activateProcessInst(String processInstanceId){	
		runtimeService.activateProcessInstanceById(processInstanceId);
	}

	/**
	 * 取消审批，删除流程实例
	 */
	public void deleteProcessInstance(Long id,String entityName){
		String deleteReason = "由于数据错误 ";
		gsMngDao.setEntityName(entityName);
		Map<String, Object> loadMap = gsMngDao.get(id);
		String processInstanceId = (String) loadMap
				.get(GsMngManager.FLOW_INS_ID);
		if (StringUtils.isNotBlank(processInstanceId)) {
			runtimeService.deleteProcessInstance(processInstanceId,
					deleteReason);
			historyService
					.deleteHistoricProcessInstance(processInstanceId);
			/*processInfoDao.batchExecute(DEL_PROCESSINFO,
					processInstanceId);*/
		}
		loadMap.put(GsMngManager.FLOW_INS_ID, null);
		loadMap.put(GsMngManager.STATUS, GsMngManager.STATUS_DRAFT);
		loadMap.put(GsMngManager.LAST_UPDATE_TIME, new Date());
		deleteProcessModel(id, entityName);
	}

	/**
	 * 恢复已审批记录的流程,可以重新启动流程实例
	 */
	public void recoverProcess(Long id,String entityName){
		gsMngDao.setEntityName(entityName);
		Map<String, Object> loadMap = gsMngDao.get(id);
		String processInstanceId = (String)loadMap.get(GsMngManager.FLOW_INS_ID);
		if(StringUtils.isNotBlank(processInstanceId)){
		ProcessInstance	processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
			if(processInstance==null){
				historyService.deleteHistoricProcessInstance(processInstanceId);
				//processInfoDao.batchExecute(DEL_PROCESSINFO,processInstanceId);
			}else{
				logger.info("该流程还在运行中，必须是已结束的流程才可以恢复");    
			}
		}		
		loadMap.put(GsMngManager.FLOW_INS_ID, null);
		loadMap.put(GsMngManager.STATUS,GsMngManager.STATUS_DRAFT);	
		loadMap.put(GsMngManager.LAST_UPDATE_TIME, new Date());
		deleteProcessModel(id,entityName);
	}
	
	/**
	 * 作废相应的流程下推单据		
	 */
	public void deleteProcessModel(Long id,String entityName){
		List<ProcessModelInfo> processModelInfo = processModelInfoDao.find(SEL_PROCESS_MODEL_INFO,entityName + "|" + id);		
		if(processModelInfo.size()>0){
			for(ProcessModelInfo pmi : processModelInfo){
				String deleteEntityName = pmi.getModelKey();
				Long deleteId = pmi.getMasterId();
				gsMngDao.setEntityName(deleteEntityName);
				Map<String, Object> map = gsMngDao.get(deleteId);
				if(map != null && !map.isEmpty()){
					map.put(GsMngManager.STATUS,GsMngManager.STATUS_CANCEL);
					map.put(GsMngManager.LAST_UPDATE_TIME, new Date());
				}				
			}	
		}		
	}
	/**
	 * 作废单据及流程下推数据
	 */
	public void invalidProcess(Long id, String entityName, String cancelReason){
		gsMngDao.setEntityName(entityName);
		Map<String, Object> loadMap = gsMngDao.get(id);
		loadMap.put(GsMngManager.CANCEL_REASON, cancelReason);
		loadMap.put(GsMngManager.STATUS, GsMngManager.STATUS_CANCEL);
		loadMap.put(GsMngManager.LAST_UPDATE_TIME, new Date());
		deleteProcessModel(id, entityName);
		//记录流程日志
		saveProcessInfo(id, entityName, "作废", cancelReason);
	}
	
	/**
	 * 审核通过
	 * 
	 * @param ids
	 * @param entityName
	 */
	public void startApprove(Long[] ids, String entityName) {
		if(null!=ids && ids.length > 0) {
			for(Long id : ids) {
				gsMngManager.setEntityName(entityName);
				gsMngManager.setUser(user);
				gsMngManager.updateColumn(id, GsMngManager.STATUS, GsMngManager.STATUS_PASS);//更新状态
				//记录日志
				saveProcessInfo(id, entityName, "审核通过", null);
			}
		}
	}
	
	/**
	 * 取消审核
	 * 
	 * @param ids
	 * @param entityName
	 */
	public void cancelApprove(Long[] ids, String entityName) {
		if(null!=ids && ids.length > 0) {
			for(Long id : ids) {
				gsMngManager.setEntityName(entityName);
				gsMngManager.setUser(user);
				gsMngManager.updateColumn(id, GsMngManager.STATUS, GsMngManager.STATUS_DRAFT);//更新状态
				//记录日志
				saveProcessInfo(id, entityName, "取消审核", null);
			}
		}
	}
	
	/**
	 * 保存审核操作日志
	 * 
	 * @param id
	 * @param entityName
	 * @param taskName
	 * @param reason
	 */
	public void saveProcessInfo(Long id, String entityName, String taskName, String reason) {
		ProcessInfo entity = new ProcessInfo();
		entity.setDealTime(new Date());
		entity.setUserId(user.getId());
		entity.setDealName(user.getNickname());
		entity.setTaskName(taskName);
		entity.setBusinessId(id);
		entity.setBusinessName(entityName);
		entity.setCountVal(1L);
		entity.setReason(reason);
		processInfoDao.save(entity);
	}
	
	/**
	 * 获取流程办理历史
	 */
	public Page<TaskInstance> searchProcessHistory(Page<TaskInstance> page,String userName,List<PropertyFilter> filters){

//			List<HistoricTaskInstance> list  = historyService.createHistoricTaskInstanceQuery().taskAssignee(userName).processFinished().listPage(page.getFirst() - 1, page.getPageSize());		
//			Long totalCount = historyService.createHistoricTaskInstanceQuery().taskAssignee(userName).processFinished().count();
//			page.setTotalCount(totalCount);
//			List<HistoricTaskInstanceEntity> listEntity =Lists.newArrayList();
//			for(HistoricTaskInstance historicTaskInstance :list){
//					String 	moduleKey =	historicTaskInstance.getProcessDefinitionId();
//					String b[] = moduleKey.split("\\:");
//					String mName = b[0];
//					String moduleName = TableEntityCache.getInstance().getModuleName(mName);
//					HistoricTaskInstanceEntity he = (HistoricTaskInstanceEntity)historicTaskInstance;
//					he.setProcessDefinitionId(moduleName);
//					listEntity.add(he);
//			}
//			page.setResult(listEntity);
			List<TaskInstance> listEntity = Lists.newArrayList();
			PropertyFilter propertyFilterParentOrg = new PropertyFilter("EQS_assignee", userName);
			filters.add(propertyFilterParentOrg);
			page = taskInstanceDao.findPage(page, filters);
			List<TaskInstance> list =  page.getResult();
			for(TaskInstance taskInstance :list){
				if(taskInstance.getEndTime()!=null){
				String 	moduleKey =	taskInstance.getProcessDefinitionId();
				String b[] = moduleKey.split("\\:");
				String mName = b[0];
				String moduleName = TableEntityCache.getInstance().getModuleName(mName);
				taskInstance.setModuleName(moduleName);
				listEntity.add(taskInstance);
				}
		}
			page.setResult(listEntity);
			return page;
	}
	/**
	 * 获取流程定义
	 */
	public Page<ProcessDefinitionInstance> searchProcessDefinitionHistory(Page<ProcessDefinitionInstance> page,List<PropertyFilter> filters){
		List<ProcessDefinitionInstance> listEntity = Lists.newArrayList();
		page = processDefDao.findPage(page, filters);
		List<ProcessDefinitionInstance> list =  page.getResult();
		for(ProcessDefinitionInstance pdi :list){
			String moduleKey =	pdi.getKey();
			String moduleName = TableEntityCache.getInstance().getModuleName(moduleKey);
			pdi.setModuleName(moduleName);
			listEntity.add(pdi);
			}
		page.setResult(listEntity);
		return page;
	}
	/**
	 * 获取流程实例
	 */
	public Page<TaskRun> searchProcessInstance(Page<TaskRun> page,List<PropertyFilter> filters){
		List<TaskRun> listEntity = Lists.newArrayList();
		page = taskRunDao.findPage(page, filters);
		List<TaskRun> list =  page.getResult();
		for(TaskRun tr :list){
			String 	moduleKey =	tr.getProcessDefinitionId();
			String b[] = moduleKey.split("\\:");
			String mName = b[0];
			String moduleName = TableEntityCache.getInstance().getModuleName(mName);
			tr.setModuleName(moduleName);
			String processInstanceId = tr.getProcessInstanceId();
			HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
			String startUser = historicProcessInstance.getStartUserId();
			tr.setStartUser(startUser);
			
			tr.setStartUserName(userDao.getUserNameByLoginName(startUser));
			tr.setAssigneeName(userDao.getUserNameByLoginName(tr.getAssignee()));
			
			String bKey = historicProcessInstance.getBusinessKey();
			if(StringUtils.isBlank(bKey)){//如果取不到businessKey，说明运行到了子流程
				bKey = (String) runtimeService.getVariable(processInstanceId,"varInBusinessKey");
			}
			String a[] = bKey.split("\\|");
			Long moduleId = Long.valueOf(a[1]);
			//查询有无任务标题规则key
			String taskTitleRuleKey = (String)runtimeService.getVariable(processInstanceId,"taskTitleRuleKey");
			if(StringUtils.isNotBlank(taskTitleRuleKey)) {
				final Map<String, Object> paramMap = new HashMap<String, Object>();
				paramMap.put("id",moduleId);
				paramMap.put("handleUserId", runtimeService.getVariable(processInstanceId,"handleUserId"));
				String titleSuffix = processInfoDao.getStringValueByParam(paramMap, taskTitleRuleKey, "");
				tr.setField(titleSuffix);
			}
			listEntity.add(tr);
		}
		page.setResult(listEntity);
		return page;
	}
	
	
	/**
	 *
	 * 结束 运行中的流程实例
	 * 
	 */
	public void endProcess(String processInstanceId){	
		String businessKey = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult().getBusinessKey();
		String b[] = businessKey.split("\\|");
		String endEntityName = b[0];
		Long endId =Long.valueOf(b[1]);
		gsMngDao.setEntityName(endEntityName);
		Map<String, Object> map = gsMngDao.get(endId);
		if(map != null && !map.isEmpty()){
			map.put(GsMngManager.STATUS,GsMngManager.STATUS_CANCEL);
			map.put(GsMngManager.CANCEL_REASON,"手动结束流程");
			map.put(GsMngManager.LAST_UPDATE_TIME, new Date());
		}
		runtimeService.deleteProcessInstance(processInstanceId, "");	
	}
	
	
	
	/**
	 * 流程跟踪图
	 * @param processInstanceId		流程实例ID
	 * @return	封装了各种节点信息
	 */
	public List<Map<String, Object>> traceProcess(String processInstanceId) throws Exception {
		List<Execution> executionList = runtimeService.createExecutionQuery().processInstanceId(processInstanceId).list();//执行实例
		/*Object property = PropertyUtils.getProperty(execution, "activityId");
		String activityId = "";
		if (property != null) {
			activityId = property.toString();
		}*/
		Set<String> actSet = new HashSet<String>();
		for(Execution execution : executionList) {
			ExecutionEntity ee = (ExecutionEntity)execution;
			String activityId = ee.getActivityId();
			if(StringUtils.isNotBlank(activityId)) {
				actSet.add(activityId);
			}
		}
		ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId)
				.singleResult();
		String processDefinitionId = "";
		if(null==processInstance) {
			HistoricProcessInstance hisProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
			processDefinitionId = hisProcessInstance.getProcessDefinitionId();
		} else {
			processDefinitionId = processInstance.getProcessDefinitionId();
		}
		ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
				.getDeployedProcessDefinition(processDefinitionId);
		List<ActivityImpl> activitiList = processDefinition.getActivities();//获得当前任务的所有节点

		List<Map<String, Object>> activityInfos = new ArrayList<Map<String, Object>>();
		for (ActivityImpl activity : activitiList) {

			boolean currentActiviti = false;
			String id = activity.getId();

			// 当前节点
			if (actSet.contains(id)) {
				currentActiviti = true;
			}

			Map<String, Object> activityImageInfo = packageSingleActivitiInfo(activity, processInstanceId, currentActiviti);

			activityInfos.add(activityImageInfo);
		}

		return activityInfos;
	}

	/**
	 * 封装输出信息，包括：当前节点的X、Y坐标、变量信息、任务类型、任务描述
	 * @param activity
	 * @param processInstanceId
	 * @param currentActiviti
	 * @return
	 */
	private Map<String, Object> packageSingleActivitiInfo(ActivityImpl activity, String processInstanceId,
			boolean currentActiviti) throws Exception {
		Map<String, Object> vars = new HashMap<String, Object>();
		Map<String, Object> activityInfo = new HashMap<String, Object>();
		activityInfo.put("currentActiviti", currentActiviti);
		setPosition(activity, activityInfo);
		setWidthAndHeight(activity, activityInfo);

		Map<String, Object> properties = activity.getProperties();
		vars.put("任务类型", parseToZhType(properties.get("type").toString()));
		ActivityBehavior activityBehavior = activity.getActivityBehavior();
		logger.debug("activityBehavior={}", activityBehavior);
		TaskDefinition taskDefinition = null;
		if (activityBehavior instanceof UserTaskActivityBehavior) {
			//当前任务的分配角色
			UserTaskActivityBehavior userTaskActivityBehavior = (UserTaskActivityBehavior) activityBehavior;
			taskDefinition = userTaskActivityBehavior.getTaskDefinition();
			
		} else if(activityBehavior instanceof MultiInstanceActivityBehavior) {
			//多实例任务
			MultiInstanceActivityBehavior miActivityBehavior = (MultiInstanceActivityBehavior)activityBehavior;
			taskDefinition = miActivityBehavior.getTaskDefinition();
		}
		if(null!=taskDefinition) {
			Set<Expression> candidateGroupIdExpressions = taskDefinition.getCandidateGroupIdExpressions();
			if (!candidateGroupIdExpressions.isEmpty()) {
				// 任务的处理角色
				setTaskGroup(vars, candidateGroupIdExpressions);
			}
		}
		List<Task> currentTask = null;
		if (currentActiviti) {
			//当前任务
			currentTask = getCurrentTaskInfo(activity.getId(), processInstanceId);
			setCurrentTaskAssignee(vars, currentTask);
			//Task tk	= taskService.createTaskQuery().processInstanceId(processInstanceId).taskDefinitionKey(activity.getId()).singleResult();			
			//setCurrentDescription(vars, tk);
			List<Task> tkList = taskService.createTaskQuery().processInstanceId(processInstanceId).taskDefinitionKey(activity.getId()).list();
			if(tkList != null && !tkList.isEmpty()) {
				for(Task tk : tkList) {
					setCurrentDescription(vars, tk);
				}
			}
		} else {
			//历史任务
			List<ProcessInfo> list = getHisTaskInfo(activity.getId(), processInstanceId);
			vars.put("hisInfo", list);
		}
		vars.put("节点说明", properties.get("documentation"));

		String description = activity.getProcessDefinition().getDescription();
		vars.put("描述", description);

		//logger.debug("trace variables: {}", vars);
		activityInfo.put("vars", vars);
		return activityInfo;
	}
	
	private List<ProcessInfo> getHisTaskInfo(String activitiId, String processInstanceId) {
		List<ProcessInfo> list  = processInfoDao.find(QUERY_PROCESSINFO_HQL, processInstanceId, activitiId);
		return list;
	}

	private void setTaskGroup(Map<String, Object> vars, Set<Expression> candidateGroupIdExpressions) {
		String roles = "";
		for (Expression expression : candidateGroupIdExpressions) {
			String expressionText = expression.getExpressionText();
			if (expressionText.startsWith("$")) {
				expressionText = expressionText.replace("${insuranceType}", "life");
			}
			//String roleName = identityService.createGroupQuery().groupId(expressionText).singleResult().getName();
			String roleName = expressionText;
			roles += roleName;
		}
		vars.put("任务所属角色", roles);
	}

	/**
	 * 设置当前处理人信息
	 * @param vars
	 * @param currentTask
	 */
	private void setCurrentTaskAssignee(Map<String, Object> vars, List<Task> currentTask) {
		// 当前处理人
		if (currentTask != null && !currentTask.isEmpty()) {
			//StringBuffer sb = new StringBuffer();
			List<String> assigneeList = new ArrayList<String>();
			//int i = 0;
			for(Task task : currentTask) {
				String ag = task.getAssignee();
				if(StringUtils.isNotBlank(ag)) {
					/*if(i > 0) {
						sb.append(",");
					}
					sb.append(task.getAssignee());*/
					assigneeList.add(ag);
				} else {
					List<IdentityLink> list = taskService.getIdentityLinksForTask(task.getId());
					if(list != null && !list.isEmpty()) {
						for(IdentityLink il : list) {
							String userId = il.getUserId();
							if(StringUtils.isNotBlank(userId)) {
								assigneeList.add(userId);
							}
						}
					}
				}
				//i++;
			}
			/*String assignee = sb.toString();
			if (StringUtils.isNotBlank(assignee)) {
				//User assigneeUser = identityService.createUserQuery().userId(assignee).singleResult();
				//String userInfo = assigneeUser.getFirstName() + " " + assigneeUser.getLastName();
				//vars.put("当前处理人", userInfo);
				vars.put("当前处理人", assignee);
			}*/
			if(!assigneeList.isEmpty()) {
				vars.put("当前处理人", StringUtils.join(assigneeList, ","));
			}
		}
	}
	/**
	 * 设置当前任务描述
	 * @param vars
	 * @param currentTask
	 */
	private void setCurrentDescription(Map<String, Object> vars, Task currentTask) {
		if (currentTask != null ) {
			String description  = "";			
			description = currentTask.getDescription();						
			if (StringUtils.isNotBlank(description)) {
				vars.put("待办原因描述", description);
			}			
		}
	}
	/**
	 * 获取当前节点信息
	 * @param activitiId
	 * @param processInstanceId
	 * @return
	 */
	private List<Task> getCurrentTaskInfo(String activitiId, String processInstanceId) {
		List<Task> currentTask = taskService.createTaskQuery().processInstanceId(processInstanceId).taskDefinitionKey(activitiId).list();
		return currentTask;
	}

	/**
	 * 设置宽度、高度属性
	 * @param activity
	 * @param activityInfo
	 */
	private void setWidthAndHeight(ActivityImpl activity, Map<String, Object> activityInfo) {
		activityInfo.put("width", activity.getWidth());
		activityInfo.put("height", activity.getHeight());
	}

	/**
	 * 设置坐标位置
	 * @param activity
	 * @param activityInfo
	 */
	private void setPosition(ActivityImpl activity, Map<String, Object> activityInfo) {
		activityInfo.put("x", activity.getX());
		activityInfo.put("y", activity.getY());
	}
	
	/**
	 * 根据流程ID或流程实例ID加载流程定义，支持输出图片或xml文件
	 * 
	 * @param processInstanceId
	 * @param processKey
	 * @param resourceType
	 * @return
	 */
	public InputStream loadProcess(String processInstanceId, String processKey, String resourceType) {
		InputStream resourceAsStream = null;
		ProcessDefinition singleResult = null;
		if(StringUtils.isNotBlank(processInstanceId)) {
			ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId)
				.singleResult();
			String processDefinitionId = "";
			if(null==processInstance) {
				HistoricProcessInstance hisProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
				processDefinitionId = hisProcessInstance.getProcessDefinitionId();
			} else {
				processDefinitionId = processInstance.getProcessDefinitionId();
			}
			singleResult = repositoryService.createProcessDefinitionQuery()
				.processDefinitionId(processDefinitionId).singleResult();
		} else {
			singleResult = repositoryService.createProcessDefinitionQuery().processDefinitionKey(processKey).latestVersion().singleResult();
		}
		String resourceName = "";
		if ("xml".equals(resourceType)) {
			resourceName = singleResult.getResourceName();
		} else {
			resourceName = singleResult.getDiagramResourceName();
		}
		resourceAsStream = repositoryService.getResourceAsStream(singleResult.getDeploymentId(), resourceName);
		return resourceAsStream;
	}
	
	/**
	 * 转换流程节点类型为中文说明
	 * @param type	英文名称
	 * @return	翻译后的中文名称
	 */
	public static String parseToZhType(String type) {
		Map<String, String> types = new HashMap<String, String>();
		types.put("userTask", "用户任务");
		types.put("serviceTask", "系统任务");
		types.put("startEvent", "开始节点");
		types.put("endEvent", "结束节点");
		types.put("exclusiveGateway", "条件判断节点(系统自动根据条件处理)");
		types.put("inclusiveGateway", "并行处理任务");
		types.put("callActivity", "子流程");
		return types.get(type) == null ? type: types.get(type);
	}
	
	/**
	 * 部署流程文件
	 * 
	 * @param flowFiles
	 */
	public void deployFlow(File... flowFiles) {
		for(File file : flowFiles) {
			InputStream fileInputStream =null;
			String fileName = file.getName();
			try {
				fileInputStream = FileUtils.openInputStream(file);
				String extension = FilenameUtils.getExtension(fileName);
				if (extension.equals("zip") || extension.equals("bar")) {
					ZipInputStream zip = new ZipInputStream(fileInputStream);
					repositoryService.createDeployment()
							.addZipInputStream(zip).deploy();
				} else if (extension.equals("png")) {
					repositoryService.createDeployment()
							.addInputStream(fileName, fileInputStream)
							.deploy();
				} else if (extension.indexOf("xml") != -1) {
					repositoryService.createDeployment()
							.addInputStream(fileName, fileInputStream)
							.deploy();
				} else if (extension.equals("bpmn")) {
					/*
					 * bpmn扩展名特殊处理，转换为bpmn20.xml
					 */
					String baseName = FilenameUtils.getBaseName(fileName);
					repositoryService
							.createDeployment()
							.addInputStream(baseName + ".bpmn20.xml",
									fileInputStream).deploy();
				}
			} catch (Exception e) {
				throw new RuntimeException("部署流程文件" + fileName + "出现异常", e);
			}finally{
				if(fileInputStream!=null){
					try {
						fileInputStream.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}
	}
	
	/**
	 * 保存实体及启动流程，同一事务处理
	 * 
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public String saveEntityAndStartProcess(String entityName, User user, String jsonSaveData, String jsonSenddata) {
		//1.保存数据
		Map<String, Object> map = jsonBinder.fromJson(jsonSaveData, HashMap.class);
		Map<String, Object> mapSend = jsonBinder.fromJson(jsonSenddata, HashMap.class);
		gsMngManager.setUser(user);
		gsMngManager.setEntityName(entityName);
		gsMngManager.saveEntity(map,mapSend);
		
		//2.提交审批
		Long id = (Long)map.get(GsMngManager.ID);
		String moduleName = StringUtils.split(entityName, ".")[0];
		this.batchStartProcessForSingleUser(new Long[]{id}, entityName, moduleName, user);
		return String.valueOf(id);
	}
}
